package mes.kanban.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

/**
 * 上传文件工具类
 * @author gjy
 *
 * 2018年2月28日下午5:45:41
 */
@Component
public class UploadFileToServerUtil {
	
	@Value("${upload.server.url}")
	private String hostname;
	
	//一般文件传输的ftp端口默认是21和20
	@Value("${upload.server.port}")
	private Integer port;
	
	@Value("${upload.server.userName}")
	private String userName;
	
	@Value("${upload.server.password}")
	private String password;
	
	@Value("${upload.server.linuxDir}")
	private String linuxDir;
	
	@Value("${upload.server.windowDir}")
	private String windowDir;
	
	private static final Logger log = LoggerFactory.getLogger(UploadFileToServerUtil.class);

	private final static String[] NAMES = {"A","B","C","D","E","F","G","H","I"};
	
	public synchronized Map<String, String> uploadToWindows(MultipartFile file){
		
		
		Map<String, String> fileMap = new HashMap<String, String>();
		
		File path = new File(windowDir);
		
		boolean mkdirOk = true;
		if (!path.getParentFile().exists()) {
			mkdirOk = path.getParentFile().mkdirs();
			mkdirOk = path.mkdir();
		}
		
		if (!mkdirOk) {
			throw new RuntimeException("文件创建失败");
		}
		
		String fileName = this.getFileName(file,fileMap);
		
		try {
			file.transferTo(new File(windowDir + "/"+fileName));
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
		}
		fileMap.put("host", windowDir);
		
		return fileMap;
		
	}
	
	
	/**
	 * 服务器必须开启ftp服务并且有ftp软件
	 * @param file
	 * @return
	 */
	public synchronized Map<String, String> uploadToLinux(MultipartFile file) {
		
		init();
		
		Map<String, String> fileMap = new HashMap<String, String>();
		
		String fileName = this.getFileName(file,fileMap);
		
		log.info("当前生成的文件名："+fileName);
		
		//创建ftp客户端 
		FTPClient ftpClient = new FTPClient(); 
		ftpClient.setControlEncoding("GBK");
		
		try {
			ftpClient.connect(hostname, port);
			ftpClient.login(userName, password);
		} catch (IOException e) {
			log.error("连接异常。。。。。。。。。。。。。。。。");
			e.printStackTrace();
			throw new RuntimeException("连接异常");
		}
		
		//如果reply返回200~300就算成功了，如果返回530密码用户名错误或当前用户无权限
		int replyCode = ftpClient.getReplyCode();
		
		log.info("连接返回值："+replyCode);
		
		if (!FTPReply.isPositiveCompletion(replyCode)) {
			try {
				ftpClient.disconnect();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}
		
		InputStream input = null;
		try {
			//使用二进制的传输方式
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			
			//判断是否存在文件夹,不存在则创建
			isExitOrDir(ftpClient, linuxDir);
			
			input = file.getInputStream();
			
			ftpClient.storeFile(fileMap.get("fileName"), input);
			
			fileMap.put("host", hostname+":"+port);
			
			return fileMap;
			
		} catch (IOException e) {
			e.printStackTrace();
			log.error("传输出错。。。。。。。。。。。。。。。");
		}finally {
			try {
				
				if (input != null) {
					input.close();
				}
				ftpClient.logout();
				
				if (ftpClient.isConnected()) {
					ftpClient.disconnect();
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
		return null;
		
	}
	
	private String getFileName(MultipartFile file,Map<String, String> fileMap) {

		// 为了不让名字重复，因此重新自定义文件名字
		int r = new Random().nextInt(NAMES.length - 1);

		String origName = file.getOriginalFilename();

		String fileName = new Date().getTime() + NAMES[r];

		if (IsNotNullValit.StringIsNotNull(origName)) {

			if (origName.length() > 2) {
				fileName += origName.substring(0, 2);
			} else {
				fileName += origName;
			}
			
			String sfix = origName.substring(origName.lastIndexOf(".")+1);
			
			fileName += "."+sfix;
			
			fileMap.put("fileName", fileName);
		}else {
			
			return null;
		}
		
		return fileName;
	}
	
	public static void isExitOrDir(FTPClient ftpClient,String dir) {
		
		try {
			FTPFile file = ftpClient.mdtmFile(dir);
			
			if (!file.isDirectory()) {
				ftpClient.makeDirectory(dir);
				ftpClient.changeWorkingDirectory(dir);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	/*
	 * 由于java的加载顺序是：静态代码块>静态方法>构造函数，
	 * 所以只能在静态代码块中对密码中包含特殊字符进行替换
	 */
	private void  init(){
		
		if (IsNotNullValit.StringIsNotNull(password)) {
			
			if(password.contains("@$@$")) {
				
				password = password.split("@$@$")[0]+"#uat";
				
			}
			
		}
		
	}

}
